package com.etlmaster.executor;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.etlmaster.executor.utils.LogWriter;

/**
 * Job对象池
 * 
 * @author Wugf
 * @date 2016-03-08
 */
public class JobPool {

	private static List<JobEntry> jobs = new ArrayList();
	private static Map<String, Object> variableList = new HashMap<String, Object>();
	private static Map<String, Object> initVariable = new HashMap<String, Object>();

	private JobPool() {

	}

	private static class JobEntry {
		private String jobName;
		private Job job;

		private JobEntry(String name, Job job) {
			this.jobName = name;
			this.job = job;
		}
	}

	public static synchronized void regist(Job job) {
		JobEntry entry = new JobEntry(job.getMeta().getName(), job);
		if (!jobs.contains(entry))
		{
			jobs.add(entry);
			redirectLogFile(job);
		}
	}

	public static void addVariable(String uuid, String key, Object value) {
		((Map<String, Object>) variableList.get(uuid)).put(key, value);
	}

	public static synchronized void addToVariableList(String uuid,
			Map<String, Object> params) {
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.putAll(params);
		variables.putAll(initVariable);

		variableList.put(uuid, variables);
	}

	public static synchronized void copyVariables(String uuid, String targetuuid) {
		Map<String, Object> variables = cloneMap((Map) variableList.get(uuid));
		variableList.put(targetuuid, variables);
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private static Map<String, Object> cloneMap(Map map) {
		ByteArrayOutputStream baos = null;
		ObjectOutputStream oos = null;
		ObjectInputStream ois = null;
		ByteArrayInputStream bais = null;
		Map cloneMap = null;
		try {
			baos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(baos);
			oos.writeObject(map);
			bais = new ByteArrayInputStream(baos.toByteArray());
			ois = new ObjectInputStream(bais);
			cloneMap = (Map) ois.readObject();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			close(baos);
			close(oos);
			close(bais);
			close(ois);
		}
		return cloneMap;
	}

	/**
	 * 关闭输出流
	 * 
	 * @param os
	 */
	private static void close(OutputStream os) {
		if (os != null) {
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 关闭输入流
	 * 
	 * @param is
	 */
	private static void close(InputStream is) {
		if (is != null) {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static Map<String, Object> getVariable(String uuid) {

		return (Map<String, Object>) variableList.get(uuid);
	}

	public static synchronized void destoryVariable(String uuid) {
		variableList.remove(uuid);
	}

	public static Job getJob(String jobName) {
		Job job = null;
		if (jobs.size() != 0) {
			for (JobEntry entry : jobs) {
				if (entry.jobName.equals(jobName)) {
					try {
						job = (Job) entry.job.clone();

					} catch (CloneNotSupportedException e) {
						LogWriter.addLog("ERROR", "{}", e.getMessage());
					}
				}
			}
			if (job == null) {
				LogWriter.addLog("DEBUG", "没取到程序{}的上下文信息", jobName);
			}
		}

		return job;
	}

	private static void redirectLogFile(Job job) {
		
		String logFileName = (job.getVariable("logFile") != null) ? job
				.getMeta().getId() + job.getVariable("logFile") : job.getMeta()
				.getId();
		Boolean isDebug=false;
		if ((job.getVariable("isDebug") != null)
				&& (job.getVariable("isDebug").equals("true"))) {
			isDebug=true;
		}
		LogWriter.initLogger(logFileName, isDebug);
	}

	public static Map<String, Object> getInitVariable() {
		return initVariable;
	}

	public static void setInitVariable(Map<String, Object> initVariable) {
		JobPool.initVariable = initVariable;
	}
}
